#include "stdafx.h"
#include "HistoryIndicatorOverlay.h"
#include "PeriodType.h"
#include "DataManager.hpp"
#include "core/data/history/history_service/history_service_def.h"
#include "HistoryIndicator.h"
#include "KLineOutput.h"
#include "ColorData.h"

using namespace sangame::jjh::core::indicator;
using namespace sangame::jjh::core::data::history;

CHistoryIndicatorOverlay::CHistoryIndicatorOverlay(SGHandle owner_handle) : CHistoryIndicatorBase(owner_handle)
{
}

BOOL CHistoryIndicatorOverlay::OnSGInitContext( SGContext* context_param )
{
	m_strIndicatorName = std::move(context_param->szparam1);
	m_strIndicatorParam = std::move(context_param->szparam2);

	return TRUE;
}

BOOL CHistoryIndicatorOverlay::OnSGGoodsChange( SGGoodsChange* goods_change_param )
{
	int goods = goods_change_param->goods;
	CPeriodType period(goods_change_param->period_type, goods_change_param->period_param);

	CHistoryData::Key key(goods, period);
	m_pData = CDataManager<CHistoryData>::Instance()->GetData(key);

	return FALSE;
}

BOOL CHistoryIndicatorOverlay::OnSGDrawBack( SGCanvas* canvas_param )
{
	CalcIndicator();

	CHistoryIndicator* indicator_ptr = (CHistoryIndicator*)owner_handle_;
	CAxes& axes = indicator_ptr->GetAxes();

	std::vector<std::shared_ptr<CKLineOutput>> line_list;
	const INDOutputLineV& outline_list = m_tResultSet.GetOutputLines();

	int nColorIndex = 0;
	axes.SetYRange(NAN_DATA, NAN_DATA);

	for(int i = 0; i < outline_list.size(); i++) {
		std::shared_ptr<CKLineOutput> line_ptr = std::make_shared<CKLineOutput>();
		line_ptr->SetData(m_pData, outline_list[i]);
		if(outline_list[i]->GetColor() == COLORREF_NULL) {
			CColorData::Key key(SGIndicator::SG_COLOR_OVERLAY, nColorIndex);
			std::shared_ptr<CColorData> data_ptr = CDataManager<CColorData>::Instance()->GetData(key);
			line_ptr->SetColor(data_ptr->GetColor());
			nColorIndex ++;
		} else {
			line_ptr->SetColor(outline_list[i]->GetColor());
		}
		line_ptr->UpdateAxes(axes);

		line_list.push_back(line_ptr);
	}

	double y_min = axes.GetYRange()[0];
	double y_max = axes.GetYRange()[1];

	if(_isnan(y_min)) {
		axes.SetYRange(0, 1);
	} else {
		if(m_strIndicatorName == "VOL" && fabs(y_min) > 1e-5) {
			y_min = 0;
		}
	}

	for(int i = 0; i < line_list.size(); i++) {
		line_list[i]->Draw(axes, canvas_param);
	}

	return FALSE;
}

BOOL CHistoryIndicatorOverlay::OnSGDrawFore( SGCanvas* canvas_param )
{
	return FALSE;
}

void CHistoryIndicatorOverlay::CalcIndicator()
{
	if(!m_pData) {
		return;
	}

	CTechnique IndexCaculator(m_pData->GetHistorySet(), NULL, NULL);
	INDIndicatorCacuParam pCacuParam;
	pCacuParam.m_strFormula = m_strIndicatorName;

	switch(m_pData->m_tKey.GetPeriod().GetType()) {
	case HP_1MIN:
		pCacuParam.m_sType = DATA_1MIN;
		break;
	case HP_5MIN:
		pCacuParam.m_sType = DATA_5MIN;
		break;
	case HP_15MIN:
		pCacuParam.m_sType = DATA_15MIN;
		break;
	case HP_30MIN:
		pCacuParam.m_sType = DATA_30MIN;
		break;
	case HP_60MIN:
		pCacuParam.m_sType = DATA_60MIN;
		break;
	case HP_240MIN:
		pCacuParam.m_sType = DATA_240MIN;
		break;
	case HP_X_MIN:
		pCacuParam.m_sType = DATA_XMIN;
		break;
	case HP_DAY:
		pCacuParam.m_sType = DATA_DAY;
		break;
	case HP_X_DAY:
		pCacuParam.m_sType = DATA_XDAY;
		break;
	case HP_WEEK:
		pCacuParam.m_sType = DATA_WEEK;
		break;
	case HP_MONTH:
		pCacuParam.m_sType = DATA_MONTH;
		break;
	default:
		throw std::runtime_error("period type not support");
	}

	pCacuParam.m_sBonusType = 0;
	pCacuParam.m_bUseFullData = TRUE;
	pCacuParam.m_nBegin = -1;
	pCacuParam.m_nEnd = -1;
	pCacuParam.m_bDrawing = true;
	pCacuParam.m_params = NULL;
	pCacuParam.m_argu = NULL;

	m_tResultSet.Clear();
	IndexCaculator.CalcIndicator(pCacuParam, m_tResultSet);
}
